package admin.data;

import java.io.IOException;
import java.util.ArrayList;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

import debug.CategoryDebug;

import models.CategoryModel;
import models.LinkModel;

public class LinkData {
	private Objectify ofy;
	
	private int limit = 20;
	
	private int page = 1;
	
	public int getLimit() {
		return limit;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public LinkData() {
		try {
			ObjectifyService.register(LinkModel.class);
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		ofy = ObjectifyService.begin();
	}
	
	public void insert(LinkModel link) {
		boolean isNew = true;
		if (link.getId() != null) {
			isNew = false;
		}
		
		/*if (link.getType().equalsIgnoreCase("featured")) {
			link.setPublished(true);
		}*/
		
		ofy.put(link);
		//update count category
		CategoryData cData = new CategoryData();
		CategoryModel category = cData.getCategory(link.getCategory());
		
		if (category != null && isNew && link.getStatus() == 2) {
			updateCount(category, 1);
		}

		if (!isNew && link.getLastCategory() != 0 && link.getLastCategory() != link.getCategory() && link.getStatus() == 2) {
			//+1 to count with new category
			if (category != null) {
				updateCount(category, 1);
			}
			//-1 to count with old category
			category = cData.getCategory(link.getLastCategory());
			if (category != null) {
				updateCount(category, -1);
			}
		}
	}
	
	public LinkModel setPublished(LinkModel link) {
		if (link.getStatus() != 2) {
			CategoryData cData = new CategoryData();
			LinkData linkData = new LinkData();
			CategoryModel category = new CategoryModel();
			category = cData.getCategory(link.getCategory());
			if (category != null) {
				updateCount(category, 1);
			}
			//Update published
			link.setStatus(2);
			update(link);
		}
		return link;
	}
	
	public LinkModel setStatus(LinkModel link, int status) {
		if (link.getStatus() != status) {
			CategoryData cData = new CategoryData();
			LinkData linkData = new LinkData();
			CategoryModel category = new CategoryModel();
			if (status == 2) {
				category = cData.getCategory(link.getCategory());
				if (category != null) {
					updateCount(category, 1);
				}
			} else {
				if (link.getStatus() == 2) {
					category = cData.getCategory(link.getCategory());
					if (category != null) {
						updateCount(category, -1);
					}
				}
			}
			//Update published
			link.setStatus(status);
			update(link);
		}
		return link;
	}
	
	public LinkModel updatePublished(LinkModel link) {
		CategoryData cData = new CategoryData();
		LinkData linkData = new LinkData();
		CategoryModel category = new CategoryModel();
		if (link.getStatus() != 2) {
			category = cData.getCategory(link.getCategory());
			if (category != null) {
				updateCount(category, 1);
			}
			//Update published
			link.setStatus(2);
			update(link);
		} else {
			category = cData.getCategory(link.getCategory());
			if (category != null) {
				updateCount(category, -1);
			}
			//Update published
			link.setStatus(0);
			update(link);
		}
		return link;
	}
	
	private void updateCount(CategoryModel category, int num) {
		CategoryData cData = new CategoryData();
		int count = 0;
		String[] parents = category.getParents().split(",");
		
		for (int i = 0 ; i < parents.length; i++) {
			category = cData.getCategory(new Long(parents[i]));
			count = category.getCount() + num;
			if (count < 0) count = 0;
			category.setCount(count);
			cData.insert(category);
		}
	}
	
	public void update(LinkModel link) {
		ofy.put(link);
	}
	
	public ArrayList<LinkModel> list() {
		ArrayList<LinkModel> links = new ArrayList<LinkModel>();
		
		int start = (page - 1) * limit;
		Query<LinkModel> q = ofy.query(LinkModel.class).limit(limit).offset(start);
		for (LinkModel link: q) {
			links.add(link);
		}
		
		return links;
	}
	
	public ArrayList<LinkModel> listByCategory(long categoryId) {
		ArrayList<LinkModel> links = new ArrayList<LinkModel>();
		
		int start = (page - 1) * limit;
		Query<LinkModel> q = ofy.query(LinkModel.class).filter("category", categoryId).limit(limit).offset(start);
		for (LinkModel link: q) {
			links.add(link);
		}
		
		return links;
	}
	
	public boolean hasLinkInDirectory(long categoryId) {
		boolean exists = false;
		
		int start = (page - 1) * limit;
		Query<LinkModel> q = ofy.query(LinkModel.class).filter("category", categoryId).limit(1);
		
		if(q.count() > 0) {
			exists = true;
		}
		
		return exists;
	}
	
	public void delete(LinkModel link) {
		//-1 to count with category
		if (link.getStatus() == 2) {
			CategoryData cData = new CategoryData();
			CategoryModel category = cData.getCategory(link.getCategory());
			if (category != null) {
				updateCount(category, -1);
			}
		}
		ofy.delete(link);
	}
	
	public LinkModel getLink(long id) {
		LinkModel link = new LinkModel();
		try {
			link = ofy.get(new Key<LinkModel>(LinkModel.class, id));
		} catch (Exception e) {
			link = null;
		}
		return link;
	}
}
